package com.d.lib.ui.view.advertswitcher;

import com.d.lib.ui.view.LogUtil;
import java.util.ArrayList;
import java.util.List;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.PageFlipper;
import ohos.app.Context;

public class AdvertSwitcher extends PageFlipper implements Component.BindStateChangedListener {
  private static final int DEFAULT_TIME_SPAN = 3000; // Default time interval

  private int mTimeSpan;
  private AnimatorProperty mInAnimation;
  private AnimatorProperty mOutAnimation;
  private Adapter mAdapter;

  public AdvertSwitcher(Context context, AttrSet attrSet, String styleName) {
    super(context, attrSet, styleName);
    initAttribute(attrSet);
    init(context);
  }

  public AdvertSwitcher(Context context, AttrSet attrSet) {
    super(context, attrSet);
    initAttribute(attrSet);
    init(context);
  }

  public AdvertSwitcher(Context context) {
    super(context);
    initAttribute(null);
    init(context);
  }

  private void initAttribute(AttrSet attrs) {
    mTimeSpan = attrs.getAttr("lib_ui_view_advertswitcher_timeSpan").isPresent() ? attrs.getAttr(
        "lib_ui_view_advertswitcher_timeSpan").get().getIntegerValue() : DEFAULT_TIME_SPAN;
  }

  private void init(Context context) {

    setFlipPeriod(mTimeSpan);

    setBindStateChangedListener(this);
  }

  @Override
  public void onComponentBoundToWindow(Component component) {
    LogUtil.debug("0012", "高度：" + getHeight() + " " + getEstimatedHeight());
    mOutAnimation = new AnimatorProperty().moveFromY(0).moveToY(-1 * getHeight()).setDuration(1200);
    mInAnimation = new AnimatorProperty().moveFromY(getHeight()).moveToY(0).setDuration(1200);
    setIncomingAnimation(mInAnimation);
    setOutgoingAnimation(mOutAnimation);
  }

  @Override
  public void onComponentUnboundFromWindow(Component component) {

  }

  /**
   * Start - onResume.
   */
  public void start() {
    if (mAdapter.getCount() <= 0) {
      return;
    }
    LogUtil.debug("0013", "高度：" + getHeight() + " " + getEstimatedHeight());
    mOutAnimation = new AnimatorProperty().moveFromY(0).moveToY(-1 * getHeight()).setDuration(1200);
    setOutgoingAnimation(mOutAnimation);
    startFlipping();
  }

  /**
   * Stop - onPause.
   */
  public void stop() {
    stopFlipping();
  }

  public Adapter getAdapter() {
    return mAdapter;
  }

  public void setAdapter(Adapter adapter) {
    mAdapter = adapter;
    mAdapter.setDataSetObservable(new Adapter.DataSetObservable() {
      @Override
      public void notifyChanged() {
        resetView();
      }
    });
    resetView();
  }

  private void resetView() {
    stop();
    removeAllComponents();
    for (int i = 0; i < mAdapter.getCount(); i++) {
      Component component = mAdapter.makeView();
      mAdapter.bindView(component, mAdapter.getItem(i), i);
      addComponent(component);
    }
  }

  public abstract static class Adapter<T> {

    protected Context mContext;
    protected List<T> mDataSet;
    protected int mResId;
    protected DataSetObservable mDataSetObservable;

    public Adapter(Context context, List<T> datas, int resId) {
      mContext = context;
      mDataSet = datas != null ? datas : new ArrayList<T>();
      mResId = resId;
    }

    public List<T> getDataSet() {
      return mDataSet;
    }

    public void setDataSet(List<T> dataSet) {
      if (mDataSet != null && mDataSet != null) {
        mDataSet.clear();
        mDataSet.addAll(dataSet);
      }
    }

    public void notifyDataSetChanged() {
      if (mDataSetObservable != null) {
        mDataSetObservable.notifyChanged();
      }
    }

    public int getCount() {
      return mDataSet != null ? mDataSet.size() : 0;
    }

    public T getItem(int position) {
      return mDataSet.get(position);
    }

    public abstract Component makeView();

    public abstract void bindView(Component view, T item, int position);

    void setDataSetObservable(DataSetObservable observer) {
      mDataSetObservable = observer;
    }

    public interface DataSetObservable {
      void notifyChanged();
    }
  }
}
